home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c
- Path: tank.news.pipex.net!pipex!warwick!bsmail!talisker!nathan
- From: nathan@pact.srf.ac.uk (Nathan Sidwell)
- Subject: Re: How do I round and truncate floats to integers?
- Message-ID: <Dn4oM5.1JK@uns.bris.ac.uk>
- Sender: usenet@uns.bris.ac.uk (Usenet news owner)
- Nntp-Posting-Host: talisker.pact.srf.ac.uk
- Organization: Inmos
- X-Newsreader: TIN [version 1.2 PL2]
- References: <4g009b$c2n@news.tuwien.ac.at> <harmon.824447677@pegasus.montclair.edu>
- Date: Wed, 21 Feb 1996 13:39:41 GMT
-
- Derek Harmon (harmon@pegasus.montclair.edu) wrote:
- : It is important to note that a C typecast only tells the compiler to treat
- : some form of data as another form of data. No change is made to the data.
- This is completely untrue. Have you actually read any C book about
- type casting?
-
- Casting converts a value from one type to another. No guarantee is made
- about the bit pattern (or even the number of bits) remaining the same, or
- not remaining the same.
-
- Now it just so happens that when the result of casting a signed int to an
- unsigned int is not implementation defined (ie the value to
- be converted is representable in both types), there is no change
- to the bit pattern, for a common representation of binary integers (twos
- complement). Many compilers extend the conversion in an implementation
- defined manner, so that there is never a change in the bit pattern.
- This may be where your confusion is coming from.
-
- The same is true of casting pointers. casting a pointer to some type to
- be a pointer to some other type changes the value of the pointer. Now
- it just so happens that for many systems, this change in value does not
- cause a change in the bit pattern -- but that's entierly implementation
- defined.
-
- : The binary representation of a double floating point value is very different
- : from that of an integer, and just telling the compiler to treat it as an int
- : will not solve your problem
-
- Casting a float to an int nearly always causes a change in the bit pattern.
- There are possibly three cases where the cast does not cause a change
- for systems when the float is in 32bit IEEE and the int is 32bit twos
- complement. These are the value (positive) zero, some positive number
- and some negative number.
- [Which particular numbers is left as an excercise to the reader.]
-
- :
- : unsigned int real2int( double real )
- : {
- : unsigned int whole = 0;
- : unsigned int pow = 10000;
- :
- : if (real > 65535.0) {
- Where did the value 65535.0 come from? Its incorrect for 16 bit ints
- (the value 32768.0 and test >= should be used). Its incorrect fo
- 16 bit unsigned ints (65536.0 and test >= should be used).
- : fputs(stderr, "real value too large in real2int().\n");
- : exit( 1 );
- : }
- : real = floor(real);
- : while ( pow > 0 )
- : if (real > (pow * 1.0)) {
- Why pow * 1.0? why not (double)pow? (actually why cast at all, the compiler
- will promote pow to type double anyway)
-
- : real -= (pow * 1.0);
- ditto.
- : whole += pow;
- : } else pow /= 10;
- :
- : return( whole );
- : }
-
- this whole routine seems to be a very inefficient way of saying
-
- if(real >= (double)INT_MAX + 1) {
- fputs(stderr, "real value too large in real2int().\n");
- exit( 1 );
- } else {
- return floor(real);
- }
-
- and a very efficient way of showing that you do not understand
- implicit promotion or type casting.
-
- : This little routine is more or less what you're looking for. It makes
- : several assumptions in that real must be positive, less than what a 16-bit
- : unsigned int can hold (the extension to a long is straightforward), but you
- ^^^^^^^^ but you're returning an int.
-
- nathan
- --
- Nathan Sidwell Holder of the Xmris home page
- Chameleon Architecture Group at SGS-Thomson, formerly Inmos
- http://www.pact.srf.ac.uk/~nathan/ Tel 0117 9707182
- nathan@inmos.co.uk or nathan@bristol.st.com or nathan@pact.srf.ac.uk
-